iT邦幫忙

2021 iThome 鐵人賽

DAY 22
0

include vs extend vs prepend

include、extend、prepend 都可以拿來引用模組(module)內的方法,他們主要的差異如下:

  • include: 可以讓我這個類別的實體繼承模組的方法,變成實體方法讓我這個類別的實體去使用。

範例:

module Animal
  def sleep
    puts "好睏,想睡了"
  end
end

class Cat
  include Animal
end

sweety = Cat.new
sweety.sleep

上述範例從 Cat 類別 include Animal,所以會讓 Cat 類別的實體繼承 Animal 的方法,讓 Cat 類別的實體可以使用。
最後會印出好睏,想睡了。

  • extend: 可以讓我這個類別具有模組的方法,但我這個類別的實體沒辦法使用模組裡面的方法,變成類別方法讓我這個類別去使用。

範例:

module Animal
  def sleep
    puts "好睏,想睡了"
  end
end

class Cat
  extend Animal
end

Cat.sleep

上述範例從 Cat 類別 extend Animal,所以會對 Cat 類別新增 Animal 的方法,讓 Cat 類別可以使用。
最後會印出好睏,想睡了。

  • prepend:跟 include 的用法一樣,差在 include 會把引用進來的模組放在類別上方,prepend 會放在類別的下方。

範例:

module Animal
  def sleep
    puts "好睏,想睡了"
  end
end

class Cat
  include Animal
end

puts Cat.ancestors

使用 ancestors 方法可以印出該類別或模組的祖宗十八代,也就是印出所有他的上層類別及引入的模組。
上述範例會依序印出 Cat、Animal、Object、Kernel、BasicObject,
可以看到 Animal 模組會在 Cat 類別的上方。

範例:

module Animal
  def sleep
    puts "好睏,想睡了"
  end
end

class Cat
  prepend Animal
end

puts Cat.ancestors

上述範例會依序印出Animal、Cat、Object、Kernel、BasicObject,
可以看到 Animal 模組會在 Cat 類別的下方。

include 外掛進來的模組優先權會比上層類別高。

當 cat 呼叫 a 方法時,因為在 C 類別找不到方法,會往上層找,這時候 A 有 include 模組也有自己的上層, 他會優先去找模組內的 a 方法,而不是 B 類別的 a 方法。

範例:

module A
  def a
    puts "我是A模組"
  end
end

class B
  def a
    puts "我是B類別"
  end
end

class C < B
  include A
end

cat = C.new
cat.a

上述範例會印出我是A模組

參考:
[1]Ruby Metaprogramming筆記(3): singleton method與singleton class
[2]Ruby Modules: include vs extend vs prepend
[3]include v.s extend 以及 require 的差別
[4]ruby.doc:ancestors


上一篇
Day 21 Ruby 類別 vs 模組
下一篇
Day 23 Ruby public vs private vs protected
系列文
網頁前後端寶石庫-礦坑補完計畫30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言